<?php
/**
 * 
 * +------------------------------------------------------------+
 * @category Db 
 * +------------------------------------------------------------+
 * 数据库驱动类基类，所有数据库驱动类都继承该类
 * +------------------------------------------------------------+
 *
 * @author anzai <236049524@qq.com>
 * @copyright http://www.judianyun.com 2012
 * @version 1.0
 *
 * Modified at : 2012-02-16 08:54:13
 *
 */
abstract class Db extends Base {
	///一组数据库相关配置
	protected $_config = array();
	
	///一组数据库连接句柄
	protected $_links = array();
	
	protected $_linkID = 0;
	
	///执行一个SELECT，SHOW，EXPLAIN 或 DESCRIBE语句的资源标识符
	protected $_queryID = null;
	
	///当前执行的SQL语句
	private $_querySql = '';
	
	///SQL语句开始执行时间
	private $_startTime = 0;
	
	///当前进行操作的表名
	protected $_table = null;
	
	///记录事务循环次数
	protected $_transTimes=0;
	
	//数据库版本号
	protected $version;
	
	protected $reflection = array();
	
	/**
	 * 构造函数
	 * @param array  $config         数据库配置
	 * @param string $from_classname 执行来源
	 */
	public function __construct($config, $reflection = array()){
		$this->_config[0] = $config;
		$this->reflection = $reflection;
	}
	
	//关闭数据库连接
	abstract function close();
	
	//连接数据库抽象方法
	abstract function connect($config='',$linkID=0);
	
	//统计查询结果的条数
	abstract function count($sql='');
	
	//释放所有SELECT，SHOW，EXPLAIN 或 DESCRIBE语句的查询的结果标识符 result 所关联的内存
	abstract protected function free();
	
	//获取查询结果所有数据集合
	abstract function getAll($sql, $result_type=null);
	
	//获取表的所有字段
	abstract function getFields($table='');
	
	//获取一条数据
	public function getOne($sql, $result_type=null){
		$result = $this->query($sql, 'getOne');
		$data = $this->_fetch_array($result, $result_type);
		$this->free();
		return $data;
	}
	
	//取得上一步 INSERT 操作产生的 ID 
	abstract function lastInsertId();
	
	//启动事务
	public function begin(){
		if($this->_transTimes<=0)
			$this->exec("START TRANSACTION");
		$this->_transTimes++;
	}
	
	//提交查询
	public function commit(){
		if($this->_transTimes==1){
			$this->_transTimes = 0;
			return $this->exec("COMMIT");
		}elseif($this->_transTimes>1){
			$this->_transTimes--;
			return true;
		}
		return false;
	}
	
	//删除数据，未指定条件和表，则默认清空当前表的数据
	public function delete($where='',$table=''){
		$table = empty($table) ? $this->_table : $table;
		if(empty($where))
			$sql = 'TRUNCATE TABLE ' . $table;
		else
			$sql = 'DELETE FROM ' . $table . ' WHERE ' . $where;
		
		return $this->exec($sql, 'delete');
	}
	
	//取得一次sql操作所影响的行数
	public function affectRow(){
		
	}
	
	//执行SQL语句
	public function exec($sql, $method = ''){
		if ($sql == ''){
			throw new E(Helper::L('CLS_DB_EXEX_SQL'), EXCEPTION_T_DB, 5, $method, $this->reflection);
		}
		$this->_querySql = $sql;
		$this->_startQueryTime();
		
		return $this->_queryID;
	}
	
	//获取数据库相关配置信息
	public function getConfig($name='', $linkId=0){
		if(empty($name))
			return $this->_config[$linkId];
		else
			return $this->_config[$linkId][$name];
	}
	
	//获取数据库连接句柄
	protected function getLink(){
		if (!isset($this->_links[$this->_linkID])){
			$this->connect($this->_config[$this->_linkID], $this->_linkID);
		}
		return $this->_links[$this->_linkID];
	}
	
	//获取当前执行执行的SQL语句
	public function getQuery(){
		return $this->_querySql;
	}
	
	//获取版本号
	public function getVersion(){
		return $this->version;
	}
	
	/**
	 * 单表通用插入数据操作，支持同时插入多条数据
	 * @param string $fields 字段
	 * @param mixed $values 值，字符串或数组（表示插入多条）
	 * @param string $table 所操作的表
	 */
	public function insert($fields, $values=null, $table=null){
		try {
			if(empty($fields))
				throw new E(Helper::L('CLS_DB_INSERT_FIELD'). '[TABLE]['.$table.']', EXCEPTION_T_DB, 5, 'insert', $this->reflection);
			if (empty($values)){
				$sql = 'INSERT INTO ' . $table . ' SET ' . $fields;
			}else{
				$table = $table === null  ? $this->_table : $table;
				$values = is_array($values) ? implode('),(', $values) : $values;
				$sql = 'INSERT INTO ' . $table . '(' . $fields . ') VALUES(' . $values . ')';
			}
			return $this->exec($sql);
		}catch (E $e){
			$e->getMsg();
		}
	}
	
	//执行查询语句
	public function query($sql, $method = ''){
		//释放前一次查询结果内存
    	if($this->_queryID)
    		$this->free();
		$this->_queryID = $this->exec($sql, $method != '' ? $method : 'query');
		
    	return $this->_queryID;
	}
	
	//事务回滚
	public function rollback(){
		if($this->_transTimes>0){
			$this->_transTimes = 0;
			return $this->exec("ROLLBACK");
		}
		return false;
	}
	
	//设置当前操作的表名
	public function setTable($table){
		$this->_table = $table;
	}
	
	///记录当前SQL语句执行花费费时间和SQL语句
	protected function _recordQuery($sql){
		$length = number_format(microtime() - $this->_startTime, 6);
		$this->_startTime = 0;
		$GLOBALS['DB_QUERYS'][] = array(
			'sec' => $length,
			'sql' => $sql
		);
	}
	
	///设置SQL语句开始执行时间
	protected function _startQueryTime(){
		$this->_startTime = microtime();
	}

	/**
	 * 单表通用更新数据操作
	 * @param string $sets 更新数据部分
	 * @param string $where 条件
	 * @param string $table 表
	 */
	public function update($sets,$where='',$table=''){
		if (empty($sets)) return true;
		$table = empty($table) ? $this->_table : $table;
		$where = empty($where) ? '' : ' WHERE ' . $where . ' ';
		$sql = 'UPDATE ' . $table . ' SET ' . $sets . $where;
		return $this->exec($sql);
	}
}

?>